package com.tank.jdk8.collecet;

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 * 自定义转换收集器
 * Created with IntelliJ IDEA.
 * User: SuQiEr
 * Date:2017/4/8 0008
 * Time: 下午 6:10
 * To change this template use File | Settings | File Templates.
 */

/**
 * T,
 * Set<T>,
 * Map<T,T>
 *
 * @param <T>
 */
@Slf4j
public class MyCollector2<T> implements Collector<T, Set<T>, Map<T,T>> {

    @Override
    public Supplier<Set<T>> supplier() {
        log.info("supplier invoked!");
        return () -> {
            log.info("return TreeSet");
            return new HashSet<>();
        };
    }

    @Override
    public BiConsumer<Set<T> ,T> accumulator() {
        log.info("accumulator invoked!");
        return (set, item )-> {
          //  System.out.println("set:"+set.hashCode());
            log.info("当前线程:{}, 当前set:{}", Thread.currentThread().getName(), set);
            set.add(item);

        };
    }

    @Override
    public BinaryOperator<Set<T>> combiner() {
        log.info("combiner invoked!");
        return (set1, set2) -> {
            log.info("set1 class:{}, set1 class:{}", set1.getClass(), set2.getClass());
            set1.addAll(set2);
            return set1;
        };
    }

    @Override
    public Function<Set<T>, Map<T,T>> finisher() {
        log.info("finisher invoked!");
        Map<T, T> map = new TreeMap<>();
        return (set) -> {
            set.stream().forEach(item -> map.put(item, item));
            return map;
        } ;
    }

    @Override
    public Set<Characteristics> characteristics() {
        log.info("accumulator characteristics!");
        //IDENTITY_FINISH: 强制将中间容器类型转换为结果容器类型,则不执行finisher方法
        //UNORDERED: 无序容器
        //CONCURRENT: 并发，多个线程会操作同一个中间容器,在accumulator 不能遍历中间容器，否则会抛出ConcurrentModificationException
        //HashSet 底层维护的是HashMap 因为在添加集合内容同时，又遍历集合，遍历集合检查初始化时集合的修改次数发生变化 modCount != expectedModCount
        return Collections.unmodifiableSet(EnumSet.of(Characteristics.UNORDERED, Characteristics.CONCURRENT));
    }

    @Test
    public void test(){
        log.info("超线程:{}", Runtime.getRuntime().availableProcessors());
        for (int i = 0; i < 1; i++) {
            List<String> list = Arrays.asList("a","b","c","zhansan", "lisi", "wangwu", "zhaoliu", "tank", "ergou","lisi",
                    "222222","1111", "444444", "333333", "00000000", "bbbbbbbbbbbb");
            Set<String> set = new HashSet<>(list);
            log.info("before set:{}", set);
            log.info("result:{}", set.parallelStream().collect(new MyCollector2<>()));
        }
    }
}









